package com.nervenets.shopping.controller.user.dto;

import com.nervenets.general.Global;
import com.nervenets.general.enumeration.Platform;
import com.nervenets.general.exception.LogicException;
import com.nervenets.general.jwt.util.JwtUtils;
import com.nervenets.general.model.GeneralModel;
import com.nervenets.general.model.MenuRole;
import com.nervenets.general.model.SecurityUser;
import com.nervenets.general.service.GlobalSecurityService;
import com.nervenets.general.utils.HttpTools;
import com.nervenets.general.utils.JodaUtils;
import com.nervenets.shopping.enumeration.UserType;
import com.nervenets.shopping.hibernate.domain.user.Manager;
import com.nervenets.shopping.hibernate.domain.user.RoleGroup;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.springframework.beans.BeanUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@EqualsAndHashCode(callSuper = true)
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class ManagerLoginDto extends GeneralModel {
    @ApiModelProperty(value = "账号")
    private String mobile;
    @ApiModelProperty(value = "昵称")
    private String name;
    @ApiModelProperty(value = "头像")
    private String avatar;
    @ApiModelProperty(value = "菜单权限")
    private Set<String> roles = new HashSet<>();
    @ApiModelProperty(value = "功能权限")
    private Set<String> permissions = new HashSet<>();
    @ApiModelProperty(value = "密钥")
    private String token;

    public ManagerLoginDto(Manager user, boolean newToken, String license, GlobalSecurityService globalSecurityService, HttpServletRequest request) {
        String platformValue = request.getHeader(Global.Constants.PLATFORM_KEY);
        Platform platform = Platform.valueOf(platformValue);
        if (!Platform.management.equals(platform)) {
            throw new LogicException("user platform not support.");
        }

        BeanUtils.copyProperties(user, this, "token", "menus", "permissions");

        final List<RoleGroup> roleGroups = user.getRoleGroups();
        for (RoleGroup roleGroup : roleGroups) {
            for (MenuRole menu : JwtUtils.getAllMenuRoles()) {
                if (roleGroup.getRoles().contains(menu.getId())) {
                    this.roles.add(menu.getCode());
                    this.permissions.addAll(analysisActions(menu, menu.getCode(), roleGroup.getRoles(), this.roles, true));
                }
            }
        }

        SecurityUser securityUser = new SecurityUser(getId(), user.getMobile(), user.getName());
        securityUser.setMenus(this.roles);
        securityUser.setPermissions(this.permissions);
        securityUser.addExtra("ip", HttpTools.getIpAddress(request));
        securityUser.addExtra("agent", request.getHeader("User-Agent"));
        securityUser.addExtra("userType", UserType.manager.name());
        securityUser.addExtra("loginTime", JodaUtils.getTimestamp());
        securityUser.addExtra("platform", platformValue);

        this.token = newToken ? globalSecurityService.getToken(securityUser, license) : null;
    }

    private List<String> analysisActions(MenuRole menu, String prefix, List<String> roleIds, Set<String> menus, boolean menuAdd) {
        List<String> actions = new ArrayList<>();
        if (null != menu.getChildren()) {
            menu.getChildren().forEach(action -> {
                if (roleIds.contains(action.getId())) {
                    if (menuAdd) menus.add(action.getCode());
                    List<String> a = new ArrayList<>();
                    a.add(prefix);
                    a.add(action.getCode());
                    final String newPrefix = String.join(":", a);
                    actions.add(newPrefix);
                    actions.addAll(analysisActions(action, newPrefix, roleIds, menus, false));
                }
            });
        }
        return actions;
    }
}
